using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Linq;

namespace EntityKit.Editor
{
    public class AssetReferenceAnalyzer : EditorWindow
    {
        private Vector2 m_ScrollPosition;
        private GUIStyle m_HeaderStyle;
        private GUIStyle m_BoxStyle;
        private GUIStyle m_ResultBoxStyle;
        private GUIStyle m_ButtonStyle;
        private bool m_StylesInitialized = false;
        private List<AssetInfo> m_UnusedAssets = new List<AssetInfo>();
        private List<AssetInfo> m_AllAssets = new List<AssetInfo>();
        private string m_SearchFilter = "";
        private string m_AssetPath = "Assets";
        private bool m_IncludeScenes = true;
        private bool m_IncludePrefabs = true;
        private bool m_IncludeTextures = true;
        private bool m_IncludeMaterials = true;
        private bool m_IncludeScripts = false;
        private bool m_IsAnalyzing = false;
        private string m_Status = "就绪";
        private float m_Progress = 0f;
        private string m_ProgressText = "";

        private class AssetInfo
        {
            public string Name;
            public string Path;
            public string Type;
            public long Size;
            public Object Asset;
            public bool IsUnused = true;
        }
        
        public static void ShowWindow()
        {
            var window = GetWindow<AssetReferenceAnalyzer>("引用分析");
            window.minSize = new Vector2(600, 500);
            window.Show();
        }

        private void OnGUI()
        {
            InitializeStyles();
            DrawHeader();
            DrawSettings();
            DrawToolBar();
            DrawResults();
        }

        private void InitializeStyles()
        {
            if (m_StylesInitialized) return;

            m_HeaderStyle = new GUIStyle(EditorStyles.largeLabel);
            m_HeaderStyle.fontStyle = FontStyle.Bold;
            m_HeaderStyle.fontSize = 16;
            m_HeaderStyle.alignment = TextAnchor.MiddleCenter;

            m_BoxStyle = new GUIStyle(EditorStyles.helpBox);
            m_BoxStyle.padding = new RectOffset(10, 10, 10, 10);
            m_BoxStyle.margin = new RectOffset(5, 5, 5, 5);

            m_ResultBoxStyle = new GUIStyle(EditorStyles.helpBox);
            m_ResultBoxStyle.padding = new RectOffset(10, 10, 10, 10);
            m_ResultBoxStyle.margin = new RectOffset(10, 10, 5, 5);

            m_ButtonStyle = new GUIStyle(GUI.skin.button);
            m_ButtonStyle.padding = new RectOffset(10, 10, 5, 5);
            m_ButtonStyle.margin = new RectOffset(5, 5, 5, 5);

            m_StylesInitialized = true;
        }

        private void DrawHeader()
        {
            GUILayout.Space(10);
            GUILayout.Label("资源引用分析工具", m_HeaderStyle);
            GUILayout.Space(5);
            
            EditorGUILayout.HelpBox("分析项目中资源的引用情况，找出未使用的资源以优化项目大小。", MessageType.Info);
            
            GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
        }

        private void DrawSettings()
        {
            EditorGUILayout.BeginVertical(m_BoxStyle);
            EditorGUILayout.LabelField("分析设置", EditorStyles.boldLabel);
            
            EditorGUILayout.BeginHorizontal();
            m_AssetPath = EditorGUILayout.TextField("分析路径:", m_AssetPath);
            if (GUILayout.Button("浏览", GUILayout.Width(60)))
            {
                string selectedPath = EditorUtility.OpenFolderPanel("选择分析路径", "Assets", "");
                if (!string.IsNullOrEmpty(selectedPath))
                {
                    if (selectedPath.StartsWith(Application.dataPath))
                    {
                        m_AssetPath = "Assets" + selectedPath.Substring(Application.dataPath.Length);
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("错误", "请选择项目Assets文件夹内的路径", "确定");
                    }
                }
            }
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.Space();
            
            EditorGUILayout.LabelField("包含的资源类型:", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();
            m_IncludeScenes = GUILayout.Toggle(m_IncludeScenes, "场景 (.unity)", GUILayout.Width(120));
            m_IncludePrefabs = GUILayout.Toggle(m_IncludePrefabs, "预制体 (.prefab)", GUILayout.Width(120));
            m_IncludeTextures = GUILayout.Toggle(m_IncludeTextures, "纹理 (.png/.jpg)", GUILayout.Width(120));
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.BeginHorizontal();
            m_IncludeMaterials = GUILayout.Toggle(m_IncludeMaterials, "材质 (.mat)", GUILayout.Width(120));
            m_IncludeScripts = GUILayout.Toggle(m_IncludeScripts, "脚本 (.cs)", GUILayout.Width(120));
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.EndVertical();
            EditorGUILayout.Space();
        }

        private void DrawToolBar()
        {
            EditorGUILayout.BeginHorizontal();
            
            GUI.enabled = !m_IsAnalyzing;
            if (GUILayout.Button("开始分析", GUILayout.Height(30)))
            {
                AnalyzeAssets();
            }
            GUI.enabled = true;
            
            if (GUILayout.Button("清除结果", GUILayout.Height(30)))
            {
                m_UnusedAssets.Clear();
                m_AllAssets.Clear();
                m_Status = "就绪";
            }
            
            EditorGUILayout.EndHorizontal();
            
            // 显示状态和进度
            EditorGUILayout.BeginVertical(m_BoxStyle);
            EditorGUILayout.LabelField("状态:", m_Status);
            if (m_IsAnalyzing)
            {
                EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), m_Progress, m_ProgressText);
            }
            EditorGUILayout.EndVertical();
            
            EditorGUILayout.Space();
        }

        private void DrawResults()
        {
            EditorGUILayout.BeginVertical(m_ResultBoxStyle);
            EditorGUILayout.LabelField($"未使用资源: {m_UnusedAssets.Count}", EditorStyles.boldLabel);
            
            if (!string.IsNullOrEmpty(m_SearchFilter))
            {
                EditorGUILayout.LabelField($"搜索过滤: \"{m_SearchFilter}\"", EditorStyles.miniLabel);
            }
            
            // 搜索框
            EditorGUILayout.BeginHorizontal();
            m_SearchFilter = EditorGUILayout.TextField("搜索:", m_SearchFilter);
            if (GUILayout.Button("清除", GUILayout.Width(60)))
            {
                m_SearchFilter = "";
            }
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.Space();
            
            m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition);
            
            if (m_UnusedAssets.Count == 0 && !m_IsAnalyzing)
            {
                if (m_AllAssets.Count == 0)
                {
                    GUILayout.FlexibleSpace();
                    GUILayout.BeginHorizontal();
                    GUILayout.FlexibleSpace();
                    var emptyStyle = new GUIStyle(EditorStyles.label);
                    emptyStyle.alignment = TextAnchor.MiddleCenter;
                    emptyStyle.normal.textColor = EditorGUIUtility.isProSkin ? 
                        new Color(0.7f, 0.7f, 0.7f) : 
                        new Color(0.4f, 0.4f, 0.4f);
                    GUILayout.Label("点击\"开始分析\"按钮查找未使用的资源。", emptyStyle);
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                    GUILayout.FlexibleSpace();
                }
                else
                {
                    GUILayout.FlexibleSpace();
                    GUILayout.BeginHorizontal();
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("未发现未使用的资源。所有资源都被引用！", EditorStyles.centeredGreyMiniLabel);
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                    GUILayout.FlexibleSpace();
                }
            }
            else
            {
                // 显示未使用资源的统计信息
                if (m_UnusedAssets.Count > 0)
                {
                    long totalSize = m_UnusedAssets.Sum(a => a.Size);
                    EditorGUILayout.LabelField($"未使用资源总大小: {FormatSize(totalSize)}", EditorStyles.boldLabel);
                    EditorGUILayout.Space();
                }
                
                // 显示资源列表
                foreach (var asset in m_UnusedAssets)
                {
                    if (ShouldShowAsset(asset))
                    {
                        DrawAssetItem(asset);
                    }
                }
            }
            
            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();
        }

        private void DrawAssetItem(AssetInfo asset)
        {
            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.ObjectField(asset.Name, asset.Asset, typeof(Object), false);
            EditorGUILayout.LabelField(asset.Type, GUILayout.Width(80));
            EditorGUILayout.LabelField(FormatSize(asset.Size), GUILayout.Width(80));
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.TextField("路径:", asset.Path);
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.Space();
            
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("在Project窗口中显示", GUILayout.Width(120)))
            {
                EditorGUIUtility.PingObject(asset.Asset);
            }
            
            if (GUILayout.Button("删除", GUILayout.Width(60)))
            {
                DeleteAsset(asset);
            }
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.EndVertical();
            EditorGUILayout.Space();
        }

        private bool ShouldShowAsset(AssetInfo asset)
        {
            if (string.IsNullOrEmpty(m_SearchFilter))
                return true;
            
            return asset.Name.ToLower().Contains(m_SearchFilter.ToLower()) ||
                   asset.Path.ToLower().Contains(m_SearchFilter.ToLower()) ||
                   asset.Type.ToLower().Contains(m_SearchFilter.ToLower());
        }

        private void AnalyzeAssets()
        {
            m_IsAnalyzing = true;
            m_Status = "正在准备分析...";
            m_Progress = 0f;
            m_ProgressText = "";
            m_UnusedAssets.Clear();
            m_AllAssets.Clear();
            Repaint();
            
            // 使用EditorApplication.delayCall来避免阻塞UI
            EditorApplication.delayCall += PerformAnalysis;
        }

        private void PerformAnalysis()
        {
            try
            {
                m_Status = "正在收集资源...";
                Repaint();
                
                // 收集所有资源
                CollectAssets();
                
                m_Status = "正在分析引用...";
                Repaint();
                
                // 分析引用关系
                AnalyzeReferences();
                
                m_Status = "分析完成";
                m_Progress = 1f;
                m_ProgressText = "完成";
            }
            catch (System.Exception e)
            {
                m_Status = "分析出错";
                UnityEngine.Debug.LogError($"资源分析出错: {e.Message}");
            }
            finally
            {
                m_IsAnalyzing = false;
                Repaint();
            }
        }

        private void CollectAssets()
        {
            m_AllAssets.Clear();
            
            // 获取所有资源GUID
            string[] allAssets = AssetDatabase.GetAllAssetPaths();
            
            m_ProgressText = $"收集资源中... (0/{allAssets.Length})";
            Repaint();
            
            int count = 0;
            foreach (string assetPath in allAssets)
            {
                count++;
                if (count % 100 == 0)
                {
                    m_Progress = 0.3f * (float)count / allAssets.Length;
                    m_ProgressText = $"收集资源中... ({count}/{allAssets.Length})";
                    Repaint();
                }
                
                // 检查是否在指定路径下
                if (!assetPath.StartsWith(m_AssetPath))
                    continue;
                
                // 检查是否为文件夹
                if (Directory.Exists(assetPath))
                    continue;
                
                // 检查文件类型
                string extension = Path.GetExtension(assetPath).ToLower();
                bool shouldInclude = false;
                
                switch (extension)
                {
                    case ".unity":
                        shouldInclude = m_IncludeScenes;
                        break;
                    case ".prefab":
                        shouldInclude = m_IncludePrefabs;
                        break;
                    case ".png":
                    case ".jpg":
                    case ".jpeg":
                    case ".tga":
                    case ".psd":
                    case ".gif":
                    case ".bmp":
                    case ".tiff":
                        shouldInclude = m_IncludeTextures;
                        break;
                    case ".mat":
                        shouldInclude = m_IncludeMaterials;
                        break;
                    case ".cs":
                        shouldInclude = m_IncludeScripts;
                        break;
                }
                
                if (!shouldInclude)
                    continue;
                
                // 加载资源
                Object asset = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object));
                if (asset == null)
                    continue;
                
                // 获取文件大小
                long size = 0;
                FileInfo fileInfo = new FileInfo(assetPath);
                if (fileInfo.Exists)
                {
                    size = fileInfo.Length;
                }
                
                AssetInfo assetInfo = new AssetInfo
                {
                    Name = Path.GetFileNameWithoutExtension(assetPath),
                    Path = assetPath,
                    Type = extension.ToUpper().Substring(1),
                    Size = size,
                    Asset = asset
                };
                
                m_AllAssets.Add(assetInfo);
            }
        }

        private void AnalyzeReferences()
        {
            m_ProgressText = "分析引用中...";
            Repaint();
            
            // 创建资源到AssetInfo的映射
            Dictionary<string, AssetInfo> assetPathMap = new Dictionary<string, AssetInfo>();
            foreach (var asset in m_AllAssets)
            {
                assetPathMap[asset.Path] = asset;
            }
            
            // 获取所有资源的依赖关系
            int count = 0;
            int total = m_AllAssets.Count;
            
            foreach (var asset in m_AllAssets)
            {
                count++;
                if (count % 50 == 0)
                {
                    m_Progress = 0.3f + 0.7f * (float)count / total;
                    m_ProgressText = $"分析引用中... ({count}/{total})";
                    Repaint();
                }
                
                // 获取该资源的依赖
                string[] dependencies = AssetDatabase.GetDependencies(asset.Path, false);
                
                // 标记被依赖的资源为已使用
                foreach (string dependencyPath in dependencies)
                {
                    if (assetPathMap.ContainsKey(dependencyPath))
                    {
                        assetPathMap[dependencyPath].IsUnused = false;
                    }
                }
            }
            
            // 收集未使用的资源
            m_UnusedAssets = m_AllAssets.Where(a => a.IsUnused).ToList();
            
            m_Progress = 1f;
            m_ProgressText = "完成";
        }

        private void DeleteAsset(AssetInfo asset)
        {
            if (EditorUtility.DisplayDialog("确认删除", 
                $"确定要删除资源 '{asset.Name}' 吗？此操作不可撤销。", 
                "删除", "取消"))
            {
                if (AssetDatabase.DeleteAsset(asset.Path))
                {
                    m_UnusedAssets.Remove(asset);
                    m_AllAssets.Remove(asset);
                    AssetDatabase.Refresh();
                    Repaint();
                    EditorUtility.DisplayDialog("成功", "资源已删除", "确定");
                }
                else
                {
                    EditorUtility.DisplayDialog("错误", "删除资源失败", "确定");
                }
            }
        }

        private string FormatSize(long bytes)
        {
            if (bytes < 1024) return $"{bytes} B";
            if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB";
            if (bytes < 1024 * 1024 * 1024) return $"{bytes / (1024.0 * 1024.0):F1} MB";
            return $"{bytes / (1024.0 * 1024.0 * 1024.0):F1} GB";
        }
    }
}